using System;
using System.Data;
using System.Drawing;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.Base.Exceptions;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.Faces.Base;
using Habanero.Faces.Win;

namespace FireStarterModeller.UI
{
    /// <summary>
    /// The A Grid control for Editing the <see cref="DMUniqueConstraintProperty"/>. This is used by
    /// <see cref="DMUniqueConstraintEditorControl"/>
    /// </summary>
    public class DMUniqueConstraintPropertiesControl : UserControlWin, IFormControl, IBusinessObjectControl
    {
        public IControlFactory ControlFactory { get; set; }
        private DMUniqueConstraint _dmUniqueConstraint;

        private readonly IGridControl _selectorAndBOEditorControl;
        private IFormHabanero _uniqueConstraintPropertyForm;

        public DMUniqueConstraintPropertiesControl(IControlFactory controlFactory)
        {
            
            if (controlFactory == null) throw new ArgumentNullException("controlFactory");
            ControlFactory = controlFactory;
            IGroupBox groupBox = controlFactory.CreateGroupBox("Constraint Properties");
           
            _selectorAndBOEditorControl = controlFactory.CreateEditableGridControl();
            IButtonGroupControl buttons = _selectorAndBOEditorControl.Buttons;
            buttons.AddButton("Edit", EditButton_ClickHandler);
            buttons["Save"].Visible = false;
            _selectorAndBOEditorControl.BusinessObjectCollection =
                new BusinessObjectCollection<DMUniqueConstraintProperty>();//Set so that initialises grid with correct properties.
            
            groupBox.Controls.Add(SelectorAndBOEditorControl);
            groupBox.Width = 400;
            SelectorAndBOEditorControl.Top = 15;
            SelectorAndBOEditorControl.Left = 5;
            SelectorAndBOEditorControl.Width = 380;
            SelectorAndBOEditorControl.FilterControl.Visible = false;
            BorderLayoutManager layoutManager = controlFactory.CreateBorderLayoutManager(this);
            layoutManager.AddControl(groupBox, BorderLayoutManager.Position.West);
            this.Size = new Size(groupBox.Width, 180);
            this.MinimumSize = this.Size;
            UpdateState();
        }

        private void EditButton_ClickHandler(object sender, EventArgs e)
        {

            try
            {
                ShowUniqueContraintPropertySelectorForm();
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }

        }

        private void ShowUniqueContraintPropertySelectorForm()
        {
            if (this.UniqueConstraint == null) return;
            CreateUniqueConstraintForm();
            _uniqueConstraintPropertyForm.ShowDialog();
        }

        private void CreateUniqueConstraintForm()
        {
            DMUniqueConstraint dmUniqueConstraint = this.UniqueConstraint;
            _uniqueConstraintPropertyForm = this.ControlFactory.CreateForm();
            DMUniqueConstraintPropertySelectorControl uniqueConstraintPropertySelectorControl = new DMUniqueConstraintPropertySelectorControl(this.ControlFactory);
            uniqueConstraintPropertySelectorControl.BusinessObject = dmUniqueConstraint;
            _uniqueConstraintPropertyForm.Controls.Add(uniqueConstraintPropertySelectorControl);
            uniqueConstraintPropertySelectorControl.SaveClicked+=((sender, e) => _uniqueConstraintPropertyForm.Close());
            uniqueConstraintPropertySelectorControl.CloseClicked+=((sender, e) => _uniqueConstraintPropertyForm.Close());
            _uniqueConstraintPropertyForm.Width = 610;
            _uniqueConstraintPropertyForm.Height = 300;
        }

        /// <summary>
        /// The <see cref="DMUniqueConstraint"/> whose <see cref="DMUniqueConstraintProperty"/> is being shown in this control
        /// </summary>
        public DMUniqueConstraint UniqueConstraint
        {
            set
            {
                try
                {
                    //DeregisterForPreviousUniqueConstraintsUpdatedEvent();
                    _dmUniqueConstraint = value;
                    //RegisterForNewUniqueConstraintsUpdatedEvent();

                    BusinessObjectCollection<DMUniqueConstraintProperty> col;
                    if (_dmUniqueConstraint != null)
                    {
                        col = _dmUniqueConstraint.UniqueConstraintProperties;
                    }
                    else
                    {
                        col = new BusinessObjectCollection<DMUniqueConstraintProperty>();
                    }
                    SelectorAndBOEditorControl.BusinessObjectCollection = col;

                    SetupPropertyColumn();
//                SetupRelatedPropertyColumn();

                    UpdateState();
                }
                catch (Exception ex)
                {
                    GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
                }
            }
            get { return _dmUniqueConstraint; }
        }
//
//        private void RegisterForNewUniqueConstraintsUpdatedEvent()
//        {
//            if (_dmUniqueConstraint != null) _dmUniqueConstraint.PropertyUpdated += UniqueConstraint_OnPropertyUpdated;
//        }
//
//        private void DeregisterForPreviousUniqueConstraintsUpdatedEvent()
//        {
//            if (_dmUniqueConstraint != null) _dmUniqueConstraint.PropertyUpdated -= UniqueConstraint_OnPropertyUpdated;
//        }

//
//        private void SetupRelatedPropertyColumn()
//        {
//            BusinessObjectCollection<DMProperty> properties = null;
//            if (_dmUniqueConstraint != null)
//            {
//                DMClass relatedClass = _dmUniqueConstraint.RelatedClass;
//                if (relatedClass != null) properties = relatedClass.Properties;
//            }
//            if (properties == null)
//            {
//                properties = new BusinessObjectCollection<DMProperty>();
//            }
        //            SetupColumnLookupWithProperties(properties, "ReverseRelationshipProperty.PropertyID");
//        }

//        private void UniqueConstraint_OnPropertyUpdated(object sender, BOPropUpdatedEventArgs e)
//        {
//            if (e.Prop.PropertyName != "RelatedClassID") return;
////            SetupRelatedPropertyColumn();
//        }

        private void SetupPropertyColumn()
        {
            BusinessObjectCollection<DMProperty> properties = null;
            if (_dmUniqueConstraint != null)
            {
                DMClass ownerClass = _dmUniqueConstraint.Class;
                if (ownerClass != null) properties = ownerClass.Properties;
            }
            if (properties == null)
            {
                properties = new BusinessObjectCollection<DMProperty>();
            }
            SetupColumnLookupWithProperties(properties, "PropertyID");
        }

        private void SetupColumnLookupWithProperties(BusinessObjectCollection<DMProperty> properties, string columnName)
        {
            DataTable dataTable = GetDataTableForPropertiesCol(properties);
            SetupComboBoxWithPropertiesDatatable(columnName, dataTable);
        }

        private void SetupComboBoxWithPropertiesDatatable(string columnName, DataTable dataTable)
        {
            IDataGridViewComboBoxColumn column = GetComboBoxColumnForProperty(columnName);
            if (column == null)
            {
                string message =
                    string.Format("The '{0}' could not be set up because no column could be found in the Grid for the column named '{1}'", this.GetType().Name, columnName);
                throw new HabaneroDeveloperException(message, message);
            }
            column.DataSource = dataTable;
            column.DisplayMember = "PropertyName";
            column.ValueMember = "PropertyID";
           ((EditableGridWin) this.SelectorAndBOEditorControl.Grid).ComboBoxClickOnce = false;
        }

        private IDataGridViewComboBoxColumn GetComboBoxColumnForProperty(string columnName)
        {
            return (IDataGridViewComboBoxColumn)_selectorAndBOEditorControl.Grid.Columns[columnName];
        }

        private DataTable GetDataTableForPropertiesCol(BusinessObjectCollection<DMProperty> properties)
        {
            ReadOnlyDataSetProvider readOnlyDataSetProvider = new ReadOnlyDataSetProvider(properties);
            return readOnlyDataSetProvider.GetDataTable(GetGridDefForProperty());
        }

        private static IUIGrid GetGridDefForProperty()
        {
            return ClassDef.Get<DMProperty>().GetUIDef("ComboLookup").UIGrid;
        }

        public IBusinessObjectCollection BusinessObjectCollection
        {
            get { return SelectorAndBOEditorControl.BusinessObjectCollection; }
        }

        private void UpdateState()
        {
            this.Enabled = _dmUniqueConstraint != null;
        }

        public void SetForm(IFormHabanero form)
        {
            
        }

        #region Implementation of IBusinessObjectControl

        /// <summary>
        ///             Gets or sets the business object being represented
        /// </summary>
        public IBusinessObject BusinessObject
        {
            get { return this.UniqueConstraint; }
            set { this.UniqueConstraint = (DMUniqueConstraint) value; }
        }

        public IGridControl SelectorAndBOEditorControl
        {
            get { return _selectorAndBOEditorControl; }
        }

        #endregion
    }
}